package com.yuuzy.qqserver.service;

import com.yuuzy.qqcommon.Message;
import com.yuuzy.qqcommon.MessageType;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 该类的一个对象和某个客户端保持通信
 */
public class ServerConnectClientThread extends Thread {
	Socket socket;
	private String userID;//连接到服务端的用户ID


	public ServerConnectClientThread(Socket socket, String userID) {
		this.socket = socket;
		this.userID = userID;
	}

	@Override
	public void run() {//这里线程处于run状态，可以发送/接受消息
		while (true) {
			System.out.println("服务端和客户端" + userID + "保持通信，读取数据...");
			try {
				Message message = null;
				//用户刚上线，有离线消息
				if (QQServer.messagehm.containsKey(userID)) {
					//离线消息不为空，则先遍历输出
					message = QQServer.messagehm.get(userID).get(0);
					QQServer.messagehm.get(userID).remove(0);
					if (QQServer.messagehm.get(userID).isEmpty()) {
						//读出该消息后，没有剩余的消息，则删除该用户的条目
						QQServer.messagehm.remove(userID);
					}
				} else {
					//没有离线消息了，就接收在线消息
					ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
					message = (Message) objectInputStream.readObject();
				}
				if (ManageClientThreads.getServerConnectClientThread(message.getGetter()) == null) {
					//首先判断消息的接收方是否在线，不在线就将该消息存入messagehm中
					if (QQServer.messagehm.containsKey(message.getGetter())) {
						//集合中已经存在该发送者了，将消息添加进集合中
						QQServer.messagehm.get(message.getGetter()).add(message);
						;
					} else {
						//否则，新建一个条目
						ArrayList<Message> messageArrayList = new ArrayList<>();
						messageArrayList.add(message);
						QQServer.messagehm.put(message.getGetter(), messageArrayList);
					}
				}
				//根据message的类型，做相应的业务处理
				else if (message.getMesType().equals(MessageType.MESSAGE_GET_ONLINE_FRIEND)) {
					//客户端要拉取在线用户列表
					System.out.println(message.getSender() + "要在线用户列表");
					String onlineUsers = ManageClientThreads.getOnlineUsers();
					Message message1 = new Message();
					message1.setMesType(MessageType.MESSAGE_RET_ONLINE_FRIEND);
					message1.setContent(onlineUsers);
					message1.setGetter(message.getSender());
					//写入到数据通道
					ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
					objectOutputStream.writeObject(message1);
				} else if (message.getMesType().equals(MessageType.MESSAGE_CLIENT_EXIT)) {
					System.out.println(message.getSender() + "退出");
					//将客户端对应的线程从集合中移除
					ManageClientThreads.removeServerConnectClientThread(message.getSender());
					socket.close();//关闭连接
					//退出while循环
					break;
				} else if (message.getMesType().equals(MessageType.MESSAGE_COMM_MES)) {
					//根据message获取getterid，然后得到对应的线程
					ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(message.getGetter());
					//转发给指定客户端
					ObjectOutputStream objectOutputStream = new ObjectOutputStream(serverConnectClientThread.socket.getOutputStream());
					objectOutputStream.writeObject(message);
				} else if (message.getMesType().equals(MessageType.MESSAGE_TO_ALL_MES)) {
					//对所有线程发送消息
					for (int i = 0; i < ManageClientThreads.getLiveNumber(); i++) {
						String[] key = ManageClientThreads.getOnlineUsers().split(" ");
						if (!key[i].equals(userID)) {//不给自己发送
							ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(key[i]);
							//转发给指定客户端
							ObjectOutputStream objectOutputStream = new ObjectOutputStream(serverConnectClientThread.socket.getOutputStream());
							objectOutputStream.writeObject(message);
						}
					}
				} else if (message.getMesType().equals(MessageType.MESSAGE_FILE_MES)) {
					//转发文件
					ServerConnectClientThread serverConnectClientThread = ManageClientThreads.getServerConnectClientThread(message.getGetter());
					//转发给指定客户端
					ObjectOutputStream objectOutputStream = new ObjectOutputStream(serverConnectClientThread.socket.getOutputStream());
					objectOutputStream.writeObject(message);
				} else {
					System.out.println("其他类型暂时不处理");
				}
			} catch (IOException |
			         ClassNotFoundException e) {
				throw new RuntimeException(e);
			}

		}

	}
}
